package com.changgou.order.service.impl;

import com.changgou.goods.feign.SkuFeign;
import com.changgou.order.dao.OrderItemMapper;
import com.changgou.order.dao.OrderMapper;
import com.changgou.order.pojo.Order;
import com.changgou.order.pojo.OrderItem;
import com.changgou.order.service.CartService;
import com.changgou.order.service.OrderService;
import com.changgou.user.feign.UserFeign;
import com.changgou.util.IdWorker;
import com.changgou.util.TokenDecode;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/****
 * @Author:itheima
 * @Description:Order业务层接口实现类
 *****/
@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private OrderItemMapper orderItemMapper;

    @Autowired
    private CartService cartService;

    @Autowired
    private IdWorker idWorker;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private SkuFeign skuFeign;

    @Autowired
    private UserFeign userFeign;

    /**
     * 根据id删除订单数据
     *
     * @param orderId 订单id
     */
    @Override
    public void deleteOrder(String orderId) {
        //从数据库中查询数据,保证查询数据的准确性
        Order order = orderMapper.selectByPrimaryKey(orderId);
        //设置当前订单参数信息
        order.setUpdateTime(new Date());
        //设置状态为支付失败
        order.setPayStatus("2");
        //修改数据库数据
        orderMapper.updateByPrimaryKeySelective(order);

        /**
         * 回滚库存
         *  1. 获取下单时所有的ids
         *  2. 调用之前编写的findChooseList方法,获取选中的商品信息
         *  3. 回滚数据
         */
        List<OrderItem> orderItemList = cartService.findChooseList(order.getIds().toArray(new String[0]), TokenDecode.getUserInfo().get("username"));
        if (orderItemList != null) {
            for (OrderItem orderItem : orderItemList) {
                String skuId = orderItem.getSkuId();
                Integer num = orderItem.getNum();
                //回滚商品库存
                skuFeign.skuNumRollback(skuId, num);
            }
        }

        //删除redis中保存的数据
        redisTemplate.boundHashOps("Order").delete(orderId);
    }

    /**
     * 根据订单id,修改订单状态
     *
     * @param orderId       订单id
     * @param transactionId 微信支付的交易流水号
     */
    @Override
    public void updateStatus(String orderId, String transactionId) {
        //从数据库中查询数据,保证查询数据的准确性
        Order order = orderMapper.selectByPrimaryKey(orderId);
        //设置order参数
        order.setUpdateTime(new Date());
        order.setPayTime(new Date());
        //交易流水号
        order.setTransactionId(transactionId);
        //已支付
        order.setPayStatus("1");
        //修改数据库
        orderMapper.updateByPrimaryKeySelective(order);

        //将redis中保存的数据删除
        redisTemplate.boundHashOps("Order").delete(orderId);
    }

    /**
     * Order条件+分页查询
     * @param order 查询条件
     * @param page 页码
     * @param size 页大小
     * @return 分页结果
     */
    @Override
    public PageInfo<Order> findPage(Order order, int page, int size){
        //分页
        PageHelper.startPage(page,size);
        //搜索条件构建
        Example example = createExample(order);
        //执行搜索
        return new PageInfo<Order>(orderMapper.selectByExample(example));
    }

    /**
     * Order分页查询
     * @param page
     * @param size
     * @return
     */
    @Override
    public PageInfo<Order> findPage(int page, int size){
        //静态分页
        PageHelper.startPage(page,size);
        //分页查询
        return new PageInfo<Order>(orderMapper.selectAll());
    }

    /**
     * Order条件查询
     * @param order
     * @return
     */
    @Override
    public List<Order> findList(Order order){
        //构建查询条件
        Example example = createExample(order);
        //根据构建的条件查询数据
        return orderMapper.selectByExample(example);
    }


    /**
     * Order构建查询对象
     * @param order
     * @return
     */
    public Example createExample(Order order){
        Example example=new Example(Order.class);
        Example.Criteria criteria = example.createCriteria();
        if(order!=null){
            // 订单id
            if(!StringUtils.isEmpty(order.getId())){
                    criteria.andEqualTo("id",order.getId());
            }
            // 数量合计
            if(!StringUtils.isEmpty(order.getTotalNum())){
                    criteria.andEqualTo("totalNum",order.getTotalNum());
            }
            // 金额合计
            if(!StringUtils.isEmpty(order.getTotalMoney())){
                    criteria.andEqualTo("totalMoney",order.getTotalMoney());
            }
            // 优惠金额
            if(!StringUtils.isEmpty(order.getPreMoney())){
                    criteria.andEqualTo("preMoney",order.getPreMoney());
            }
            // 邮费
            if(!StringUtils.isEmpty(order.getPostFee())){
                    criteria.andEqualTo("postFee",order.getPostFee());
            }
            // 实付金额
            if(!StringUtils.isEmpty(order.getPayMoney())){
                    criteria.andEqualTo("payMoney",order.getPayMoney());
            }
            // 支付类型，1、在线支付、0 货到付款
            if(!StringUtils.isEmpty(order.getPayType())){
                    criteria.andEqualTo("payType",order.getPayType());
            }
            // 订单创建时间
            if(!StringUtils.isEmpty(order.getCreateTime())){
                    criteria.andEqualTo("createTime",order.getCreateTime());
            }
            // 订单更新时间
            if(!StringUtils.isEmpty(order.getUpdateTime())){
                    criteria.andEqualTo("updateTime",order.getUpdateTime());
            }
            // 付款时间
            if(!StringUtils.isEmpty(order.getPayTime())){
                    criteria.andEqualTo("payTime",order.getPayTime());
            }
            // 发货时间
            if(!StringUtils.isEmpty(order.getConsignTime())){
                    criteria.andEqualTo("consignTime",order.getConsignTime());
            }
            // 交易完成时间
            if(!StringUtils.isEmpty(order.getEndTime())){
                    criteria.andEqualTo("endTime",order.getEndTime());
            }
            // 交易关闭时间
            if(!StringUtils.isEmpty(order.getCloseTime())){
                    criteria.andEqualTo("closeTime",order.getCloseTime());
            }
            // 物流名称
            if(!StringUtils.isEmpty(order.getShippingName())){
                    criteria.andEqualTo("shippingName",order.getShippingName());
            }
            // 物流单号
            if(!StringUtils.isEmpty(order.getShippingCode())){
                    criteria.andEqualTo("shippingCode",order.getShippingCode());
            }
            // 用户名称
            if(!StringUtils.isEmpty(order.getUsername())){
                    criteria.andLike("username","%"+order.getUsername()+"%");
            }
            // 买家留言
            if(!StringUtils.isEmpty(order.getBuyerMessage())){
                    criteria.andEqualTo("buyerMessage",order.getBuyerMessage());
            }
            // 是否评价
            if(!StringUtils.isEmpty(order.getBuyerRate())){
                    criteria.andEqualTo("buyerRate",order.getBuyerRate());
            }
            // 收货人
            if(!StringUtils.isEmpty(order.getReceiverContact())){
                    criteria.andEqualTo("receiverContact",order.getReceiverContact());
            }
            // 收货人手机
            if(!StringUtils.isEmpty(order.getReceiverMobile())){
                    criteria.andEqualTo("receiverMobile",order.getReceiverMobile());
            }
            // 收货人地址
            if(!StringUtils.isEmpty(order.getReceiverAddress())){
                    criteria.andEqualTo("receiverAddress",order.getReceiverAddress());
            }
            // 订单来源：1:web，2：app，3：微信公众号，4：微信小程序  5 H5手机页面
            if(!StringUtils.isEmpty(order.getSourceType())){
                    criteria.andEqualTo("sourceType",order.getSourceType());
            }
            // 交易流水号
            if(!StringUtils.isEmpty(order.getTransactionId())){
                    criteria.andEqualTo("transactionId",order.getTransactionId());
            }
            // 订单状态,0:未完成,1:已完成，2：已退货
            if(!StringUtils.isEmpty(order.getOrderStatus())){
                    criteria.andEqualTo("orderStatus",order.getOrderStatus());
            }
            // 支付状态,0:未支付，1：已支付，2：支付失败
            if(!StringUtils.isEmpty(order.getPayStatus())){
                    criteria.andEqualTo("payStatus",order.getPayStatus());
            }
            // 发货状态,0:未发货，1：已发货，2：已收货
            if(!StringUtils.isEmpty(order.getConsignStatus())){
                    criteria.andEqualTo("consignStatus",order.getConsignStatus());
            }
            // 是否删除
            if(!StringUtils.isEmpty(order.getIsDelete())){
                    criteria.andEqualTo("isDelete",order.getIsDelete());
            }
        }
        return example;
    }

    /**
     * 删除
     * @param id
     */
    @Override
    public void delete(String id){
        orderMapper.deleteByPrimaryKey(id);
    }

    /**
     * 修改Order
     * @param order
     */
    @Override
    public void update(Order order){
        orderMapper.updateByPrimaryKey(order);
    }

    /**
     * 增加Order
     * @param order
     */
    @GlobalTransactional//开启分布式事务
    @Override
    public Order add(Order order){
        //设置当前订单的id====  一笔订单,多个商品,一起结算
        order.setId("No" + idWorker.nextId());

        //获取当前购物车数据
        List<OrderItem> orderItemList = redisTemplate.boundHashOps("Cart_" + order.getUsername()).values();
        //定义当前结算商品数量和总金额
        Integer num = 0;
        Integer totalMoney = 0;

        //记录当前商品操作数量信息
        Map<String, Integer> dataMap = new HashMap<>();
        if (orderItemList != null) {
            //遍历购物车中的所有数据
            for (OrderItem orderItem : orderItemList) {
                //遍历选中的商品数据
                for (String id : order.getIds()) {
                    //根据id匹配选中的商品数据
                    if (orderItem.getSkuId().equals(id)) {
                        //设置当前订单id
                        orderItem.setOrderId(order.getId());
                        //设置orderItem的id
                        orderItem.setId("No" + idWorker.nextId());
                        //循环添加orderItem
                        orderItemMapper.insertSelective(orderItem);

                        //清空勾选的购物车数据
                        redisTemplate.boundHashOps("Cart_" + order.getUsername()).delete(id);

                        //统计商品总数量
                        num += orderItem.getNum();
                        totalMoney += orderItem.getMoney();

                        //记录操作数据
                        dataMap.put(id, orderItem.getNum());
                        break;
                    }
                }
            }
            //设置当前订单购买总数量
            order.setTotalNum(num);
            //设置当前订单购买总金额
            order.setTotalMoney(totalMoney);
            //设置订单创建时间和订单更新时间
            order.setCreateTime(new Date());
            order.setUpdateTime(order.getCreateTime());
            //设置当前订单状态信息
            order.setOrderStatus("0");//未完成
            order.setPayStatus("0");//未支付
            order.setConsignStatus("0");//未发货
            order.setIsDelete("0");//未删除

            //添加订单信息
            orderMapper.insertSelective(order);

            //减少库存
            skuFeign.reduceCount(dataMap);

            //增加积分
            userFeign.addUserPoint(10);

            //将订单信息存入redis,降低数据库的访问频次  == 线上支付
            if ("1".equalsIgnoreCase(order.getPayType())) {
                redisTemplate.boundHashOps("Order").put(order.getId(), order);
            }
        }
        return order;
    }

    /**
     * 根据ID查询Order
     * @param id
     * @return
     */
    @Override
    public Order findById(String id){
        return  orderMapper.selectByPrimaryKey(id);
    }

    /**
     * 查询Order全部数据
     * @return
     */
    @Override
    public List<Order> findAll() {
        return orderMapper.selectAll();
    }

}
